/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.MaintainPlanAffairDTO;
import org.springblade.modules.admin.entity.MaintainPlanContent;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.service.IMaintainPlanContentService;
import org.springblade.modules.admin.service.impl.PlanContentExcelServiceImpl;
import org.springblade.modules.admin.vo.plan.AffairListVo;
import org.springblade.modules.admin.vo.plan.AffairStatusVo;
import org.springblade.modules.admin.vo.plan.MaintainPlanAffairDetailVO;
import org.springblade.modules.admin.vo.user.UserAffairAndCheckVo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.admin.entity.MaintainPlanAffair;
import org.springblade.modules.admin.vo.MaintainPlanAffairVO;
import org.springblade.modules.admin.wrapper.MaintainPlanAffairWrapper;
import org.springblade.modules.admin.service.IMaintainPlanAffairService;
import org.springblade.core.boot.ctrl.BladeController;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 事务工单表 控制器
 *
 * @author ysq
 * @since 2023-11-10
 */
@RestController
@AllArgsConstructor
@RequestMapping("admin/maintain/plan/affair")
@Api(value = "事务工单表", tags = "事务工单表接口")
public class MaintainPlanAffairController extends BladeController {

	private final IMaintainPlanAffairService maintainPlanAffairService;

	private final IMaintainPlanContentService maintainPlanContentService;

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入maintainPlanAffair")
	public R<MaintainPlanAffairDetailVO> detail(Long planId) {
		MaintainPlanAffairDetailVO detail = maintainPlanAffairService.detail(planId);
		return R.data(detail);
	}

	/**
	 * 分页 事务工单表
	 */
	@PostMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入maintainPlanAffair")
	public R<IPage<AffairListVo>> list(@RequestBody MaintainPlanAffairDTO maintainPlanAffairDTO) {
		IPage<AffairListVo> pages = maintainPlanAffairService.list(maintainPlanAffairDTO);
		return R.data(pages);
	}


	/**
	 * 新增 事务工单表
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入maintainPlanAffair")
	public R save(@Valid @RequestBody MaintainPlanAffairVO maintainPlanAffair) {
		if (maintainPlanAffair.getUserIds() == null) {
			maintainPlanAffair.setUserIds(new ArrayList<>(0));
		}
		return R.data(maintainPlanAffairService.add(maintainPlanAffair));
	}

	/**
	 * 修改 事务工单表
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入maintainPlanAffair")
	public R update(@Valid @RequestBody MaintainPlanAffair maintainPlanAffair) {
		Long elevatorId = maintainPlanAffair.getElevatorId();
		if (elevatorId != null) {
			MaintainPlanAffair planAffair = maintainPlanAffairService.getById(maintainPlanAffair.getId());
			MaintainPlanContent planContent = maintainPlanContentService.getById(planAffair.getPlanId());
			planContent.setElevatorId(elevatorId);
			maintainPlanContentService.updateById(planContent);
		}
		return R.data(maintainPlanAffairService.updateById(maintainPlanAffair));
	}


	/**
	 * 获取人员的待开始和进行中的工单
	 * 用于用户离职人员的校验
	 *
	 * @param userId 用户iD
	 * @return 数据集
	 */
	@GetMapping("getPlanListOfUserId")
	@ApiOperationSupport(order = 33)
	@ApiOperation(value = "人员离职进行中工单")
	public R<List<AffairListVo>> getPlanListOfUserId(String userId) {
		return R.data(maintainPlanAffairService.getPlanListOfUserId(userId));
	}


	@GetMapping("getAffairStatus")
	@ApiOperation(value = "工单状态统计")
	public R<AffairStatusVo> getAffairStatus() {
		AffairStatusVo affairStatusVo = new AffairStatusVo();
		List<AffairStatusVo> affairStatus = maintainPlanAffairService.getAffairStatus();
		if (affairStatus.size() > 0) {
			int sum1 = affairStatus.stream().filter(o -> o.getPlanStatus() == TaskStatusEnum.SW_ALLOCATION.getStatus()).mapToInt(AffairStatusVo::getCounts).sum();
			int sum2 = affairStatus.stream().filter(o -> o.getPlanStatus() == TaskStatusEnum.SW_TO_START.getStatus()).mapToInt(AffairStatusVo::getCounts).sum();
			int sum3 = affairStatus.stream().filter(o -> o.getPlanStatus() == TaskStatusEnum.SW_UNDER_WAY.getStatus()).mapToInt(AffairStatusVo::getCounts).sum();
			int sum4 = affairStatus.stream().filter(o -> o.getPlanStatus() == TaskStatusEnum.SW_SIGN_FINISH.getStatus()).mapToInt(AffairStatusVo::getCounts).sum();
			int sum5 = affairStatus.stream().filter(o -> o.getPlanStatus() == TaskStatusEnum.SW_CLOSED.getStatus()).mapToInt(AffairStatusVo::getCounts).sum();
			affairStatusVo.setDisPlanCounts(sum1);
			affairStatusVo.setDisSignCounts(sum2);
			affairStatusVo.setEnSignCounts(sum3);
			affairStatusVo.setFinishCounts(sum4);
			affairStatusVo.setCloseCounts(sum5);
		}
		int sum = affairStatus.stream().mapToInt(AffairStatusVo::getCounts).sum();
		affairStatusVo.setPlanCounts(sum);
		return R.data(affairStatusVo);
	}

	/**
	 * 分页 事务工单表
	 */
	@PostMapping("/down/excel")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "下载", notes = "传入maintainPlanAffair")
	public void downExcel(HttpServletResponse response, @RequestBody MaintainPlanAffairDTO maintainPlanAffairDTO) throws IOException {
		Integer[] emerProcTypes = {0, 1, 2, 3, 4};
		List<AffairListVo> listVoList;
		//表示离职人员
		Integer isUserStatus = 1;
		if (Convert.toInt(maintainPlanAffairDTO.getIsUserStatus(), -1).equals(isUserStatus)) {
			listVoList = maintainPlanAffairService.getPlanListOfUserId(maintainPlanAffairDTO.getPlanUserId());
		} else {
			listVoList = maintainPlanAffairService.list(maintainPlanAffairDTO, null);
		}
		ExcelWriter excelWriter = null;
		ServletOutputStream outputStream = response.getOutputStream();
		try {
			List<List<String>> rows = new ArrayList<>();
			List<String> title = CollUtil.newArrayList("项目名称", "电梯位置", "任务编号", "任务类型", "执行人", "创建人", "创建时间", "执行时间", "开始时间", "完成时间", "任务耗时(分钟)", "紧急程度", "状态");
			rows.add(title);
			for (AffairListVo affairListVo : listVoList) {
				List<String> row = new ArrayList<>();
				row.add(affairListVo.getBuildingName());
				row.add(affairListVo.getElevatorAddress());
				row.add(affairListVo.getPlanId().toString());
				row.add("事务工单");
				row.add(Convert.toStr(affairListVo.getUserNames(), ""));
				row.add(Convert.toStr(affairListVo.getCreateName(), ""));
				row.add(DateUtil.format(affairListVo.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
				row.add(DateUtil.format(affairListVo.getPlanDate(), "yyyy-MM-dd"));
				row.add(Convert.toStr(DateUtil.format(affairListVo.getPlanBeginTime(), "yyyy-MM-dd HH:mm:ss"), "/"));
				row.add(Convert.toStr(DateUtil.format(affairListVo.getPlanBeginTime(), "yyyy-MM-dd HH:mm:ss"), "/"));
				row.add(Convert.toStr(affairListVo.getWorkMinute(), "/"));
				//1:非常紧急2:紧急3:普通4:较低
				if (affairListVo.getEmerProcType().equals(emerProcTypes[1])) {
					row.add("非常紧急");
				} else if (affairListVo.getEmerProcType().equals(emerProcTypes[2])) {
					row.add("紧急");
				} else if (affairListVo.getEmerProcType().equals(emerProcTypes[3])) {
					row.add("普通");
				} else if (affairListVo.getEmerProcType().equals(emerProcTypes[4])) {
					row.add("较低");
				} else {
					row.add("/");
				}
				row.add(TaskStatusEnum.getTaskName(MaintainPlanContentEnum.MAINTAIN_AFFAIR.getId(), affairListVo.getPlanStatus()));
				rows.add(row);
			}
			String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
			setResponseHeader(response, fileName);
			excelWriter = ExcelUtil.getBigWriter(rows.size());
			excelWriter.write(rows, true);
			excelWriter.flush(outputStream, true);
		} catch (
			Exception e) {
			e.printStackTrace();
		} finally {
			if (excelWriter != null) {
				excelWriter.close();
			}
			outputStream.close();
		}
	}

	/**
	 * 功能描述: 发送响应流方法
	 */
	private void setResponseHeader(HttpServletResponse response, String fileName) {
		try {
			try {
				fileName = new String(fileName.getBytes(), "ISO8859-1");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setContentType("application/octet-stream;charset=ISO8859-1");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
